package com.nifostasky.comic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nifostasky.comic.entitys.SysDict;
import com.nifostasky.comic.exceptions.BusinessException;
import com.nifostasky.comic.service.SysDictService;
import com.nifostasky.comic.mapper.SysDictMapper;
import com.nifostasky.comic.utils.PageUtils;
import com.nifostasky.comic.vos.ResultCode;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {

    @Override
    public IPage<SysDict> findListPage(PageUtils pageUtils, SysDict sysDict) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(sysDict.getDictName()),SysDict::getDictName,sysDict.getDictName());
        queryWrapper.eq(StringUtils.isNotBlank(sysDict.getDictCode()),SysDict::getDictCode,sysDict.getDictCode());
        queryWrapper.eq(Objects.nonNull(sysDict.getDomainId()),SysDict::getDomainId,sysDict.getDomainId());
        queryWrapper.eq(Objects.nonNull(sysDict.getParentId()),SysDict::getParentId,sysDict.getParentId());
        queryWrapper.eq(Objects.nonNull(sysDict.getDomainCode()),SysDict::getDomainCode,sysDict.getDomainCode());
        queryWrapper.orderByAsc(SysDict::getSort);
        IPage<SysDict> page = this.baseMapper.selectPage(new Page<>(pageUtils.getPageIndex(),pageUtils.getPageSize()),queryWrapper);
        return page;
    }

    @Override
    public List<SysDict> findList(SysDict sysDict) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(sysDict.getDictName()),SysDict::getDictName,sysDict.getDictName());
        queryWrapper.eq(StringUtils.isNotBlank(sysDict.getDictCode()),SysDict::getDictCode,sysDict.getDictCode());
        queryWrapper.eq(Objects.nonNull(sysDict.getDomainId()),SysDict::getDomainId,sysDict.getDomainId());
        queryWrapper.eq(Objects.nonNull(sysDict.getParentId()),SysDict::getParentId,sysDict.getParentId());
        queryWrapper.orderByAsc(SysDict::getSort);
        return this.list(queryWrapper);
    }

    @Override
    public Boolean saveOrUpdateData(SysDict sysDict) {
        //验证编码是否重复
        SysDict dict = this.getDictByCode(sysDict.getDictCode());
        if (Objects.nonNull(dict)) {
            if (Objects.isNull(sysDict.getId())) {
                throw new BusinessException(ResultCode.DICT_DOMAIN_CODE_EXIST);
            } else if (Objects.nonNull(sysDict.getId()) && !Objects.equals(sysDict.getId(), dict.getId())) {
                throw new BusinessException(ResultCode.DICT_DOMAIN_CODE_EXIST);
            }
        }
        //验证通一个大类下字典值不能重复
        SysDict onlyValueDict = this.getDictByDomainCodeAndValue(sysDict.getDomainCode(),sysDict.getDictValue());
        if (Objects.nonNull(onlyValueDict)) {
            if (Objects.isNull(sysDict.getId())) {
                throw new BusinessException(ResultCode.DICT_DOMAIN_VALUE_EXIST);
            } else if (Objects.nonNull(sysDict.getId()) && !Objects.equals(sysDict.getId(), onlyValueDict.getId())) {
                throw new BusinessException(ResultCode.DICT_DOMAIN_VALUE_EXIST);
            }
        }
        return this.saveOrUpdate(sysDict);
    }

    @Override
    public SysDict getDictByCode(String dictCode) {
        LambdaQueryWrapper<SysDict> qw = new LambdaQueryWrapper<>();
        qw.eq(SysDict::getDictCode,dictCode);
        return this.getOne(qw);
    }

    @Override
    public Boolean deleteByIds(String ids) {
        if(StringUtils.isBlank(ids)){
            throw new BusinessException(ResultCode.REQUIRED_PARAMS);
        }
        List<String> listId = this.handleListStr(ids);
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(SysDict::getParentId,listId);
        List<SysDict> listDict = this.list(queryWrapper);
        if(CollectionUtils.isNotEmpty(listDict)){
            throw new BusinessException("存在子字典，不允许删除");
        }
        return this.removeByIds(listId);
     }

    @Override
    public List<SysDict> findDataListByDomainCode(String domainCode) {
        if(StringUtils.isBlank(domainCode)){
            return null;
        }
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDict::getDomainCode,domainCode);
        return this.list(queryWrapper);
    }

    @Override
    public Map<String,List<SysDict>> findDataListAllByDomainCode(String domainCodeStr) {
        List<String> listCode = this.handleListStr(domainCodeStr);
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CollectionUtils.isNotEmpty(listCode),SysDict::getDomainCode,listCode);
        List<SysDict> listDict = this.list(queryWrapper);
        if(CollectionUtils.isEmpty(listDict)){
            return null;
        }
        Map<String,List<SysDict>> map =listDict.stream().collect(Collectors.groupingBy(SysDict::getDomainCode));
        return map;
    }

    @Override
    public SysDict getDictByDomainCodeAndValue(String domainCode, String value) {
        LambdaQueryWrapper<SysDict> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDict::getDomainCode,domainCode);
        queryWrapper.eq(SysDict::getDictValue,value);
        return this.getOne(queryWrapper);
    }

    private List<String> handleListStr(String str){
        if(StringUtils.isBlank(str)){
            return null;
        }
        List<String> listStr = Arrays.asList(str.split(","));
        return listStr;
    }
}
